//
//  NodeViewController.m
//  FDSMeshLibDemo
//
//  Created by LEIPENG on 2022/6/9.
//

#import "NodeViewController.h"
#import "SearchViewController.h"
#import "TestViewController.h"
#import "AddNodeViewController.h"
#import "NodeListTableViewCell.h"
#import "ListCreatTableViewCell.h"

@interface NodeViewController ()<UITableViewDataSource, UITableViewDelegate, GetNodeEventResponseDelegate, GetListCreatResponseDelegate, JMDropMenuDelegate>

@property (nonatomic, strong) MeshTool *meshTool;
@property (nonatomic, strong) NSMutableArray *filterList;
@property (nonatomic, assign) NSInteger selectRow;
@property (weak, nonatomic) IBOutlet UILabel *deviceCountLabel;

@property (weak, nonatomic) IBOutlet UIButton *addButton;
@property (weak, nonatomic) IBOutlet UITableView *tableview;

@end

@implementation NodeViewController

#pragma mark - Initialize
- (void)InitializeCode{
    self.meshTool = [MeshTool shareInstance];
    self.title = @"节点";
    self.selectRow = 0;
    self.addButton.layer.cornerRadius = 15;
    self.addButton.layer.masksToBounds = YES;
    self.filterList = [NSMutableArray array];
    // 检测和刷新节点在线状态
    [FDSMeshApi refreshWorkNormal];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationRefreshNodes) name:FDS_REFRESH_NODES_STATE object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationWillEnterForeground) name:UIApplicationWillEnterForegroundNotification object:nil];
    NSLog(@"当前MeshUUID：%@",[FDSMeshCoreApi getMeshUUID]);
    NSLog(@"当前NetworkKey：%@",[FDSMeshCoreApi getMeshNetworkKey]);
    NSLog(@"当前AppUUID：%@",[FDSMeshCoreApi getMeshAppUUID]);
    NSLog(@"当前网络地址：%04X",[FDSMeshCoreApi getAllocatedUnicastRangeLowAddress]);
    
    UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithTitle:@"Mesh OTA" style:(UIBarButtonItemStylePlain) target:self action:@selector(clickRightItem)];
    self.navigationItem.rightBarButtonItem = rightItem;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    [self InitializeCode];
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [self.meshTool refreshNodesAndGroups];
    self.deviceCountLabel.text = [NSString stringWithFormat:@"设备列表：%lu",(unsigned long)self.meshTool.nodeListWhitOutGroup.count];
    [self.tableview reloadData];
}
#pragma mark - NSNotificationCenter
- (void)applicationWillEnterForeground{
    // 从后台进入前台，检测和刷新节点在线状态
    [FDSMeshApi refreshWorkNormal];
}
- (void)notificationRefreshNodes{
    NSLog(@"--- 刷新节点数据 ---");
    WeakSelf
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.meshTool refreshNodesAndGroups];
        [weakSelf.tableview reloadData];
    });
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(configNodePublish) object:nil];
    [self performSelector:@selector(configNodePublish) withObject:nil afterDelay:2.0];
}
- (void)configNodePublish{
    WeakSelf
    dispatch_async(dispatch_get_main_queue(), ^{
        [weakSelf.meshTool refreshNodesAndGroups];
        [weakSelf.tableview reloadData];
    });
    // 配置节点自动上报状态
    [FDSMeshApi configNodePuslishState:YES nodeList:self.meshTool.nodeList resultAction:^(BOOL isSuccess) {
        NSLog(@"--- configNodePuslishState ---");
        // 注意：配置上报后必须保存MESH JSON，否则配置下次重新加载不生效
        self.meshTool.studioModel.meshJson = [FDSMeshApi getCurrentMeshJson];
        [self.meshTool codingMeshData:self.meshTool.meshModel];
    }];
}
#pragma mark - UIButton
- (void)clickRightItem{
    UIAlertController *sheetAlert = [UIAlertController alertControllerWithTitle:@"Mesh OTA" message:@"选择设备类型" preferredStyle:(UIAlertControllerStyleActionSheet)];
    [sheetAlert addAction:[UIAlertAction actionWithTitle:@"非PA设备" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
        AddNodeViewController *viewController = [[AddNodeViewController alloc] init];
        viewController.firmwareType = FirmwareType_NoPa;
        viewController.functionType = FunctionType_MeshOTA;
        viewController.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:viewController animated:YES];
    }]];
    [sheetAlert addAction:[UIAlertAction actionWithTitle:@"PA设备" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
        AddNodeViewController *viewController = [[AddNodeViewController alloc] init];
        viewController.firmwareType = FirmwareType_Pa;
        viewController.functionType = FunctionType_MeshOTA;
        viewController.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:viewController animated:YES];
    }]];
    [sheetAlert addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {}]];
    if (DEVICE_ISIPAD) {
        sheetAlert.popoverPresentationController.sourceView = self.view;
        sheetAlert.popoverPresentationController.sourceRect = CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
    }
    [self presentViewController:sheetAlert animated:YES completion:nil];
}
- (IBAction)clickAllSwitchBtn:(UIButton *)sender {
    sender.selected = !sender.selected;
    [FDSCommandApi changeLightSwitch:0xFFFF isSwitch:sender.selected];
}
- (IBAction)clickCreateBtn:(UIButton *)sender {
    [self getListCreatResponse];
}
- (IBAction)clickBatchRemoveBtn:(UIButton *)sender {
    WeakSelf
    [SVProgressHUD show];
    [FDSMeshApi refreshNodesAndGroups];
    NSArray *nodeList = [NSArray arrayWithArray:self.meshTool.nodeListWhitOutGroup];
    [self.tableview reloadData];
    __block NSInteger progressIndex = 0;
    [FDSMeshApi batchRemoveNode:nodeList progressAction:^(BOOL success, FDSMeshNodeModel * _Nonnull nodeModal) {
        progressIndex++;
        CGFloat progressPercent = (CGFloat)progressIndex/nodeList.count;
        [SVProgressHUD showProgress:progressPercent status:[NSString stringWithFormat:@"退网进度：%.0f%@",progressPercent*100.0, @"%"]];
    } resultAction:^(BOOL finish) {
        weakSelf.meshTool.studioModel.meshJson = [FDSMeshApi getCurrentMeshJson];
        [weakSelf.meshTool codingMeshData:weakSelf.meshTool.meshModel];
        dispatch_async(dispatch_get_main_queue(), ^{
            [SVProgressHUD dismiss];
            [self.meshTool refreshNodesAndGroups];
            self.deviceCountLabel.text = [NSString stringWithFormat:@"设备列表：%lu",(unsigned long)self.meshTool.nodeListWhitOutGroup.count];
            [weakSelf.tableview reloadData];
        });
    }];
}
#pragma mark - GetListCreatResponseDelegate
- (void)getListCreatResponse{
    SearchViewController *viewController = [[SearchViewController alloc] init];
    viewController.hidesBottomBarWhenPushed = YES;
    [self.navigationController pushViewController:viewController animated:YES];
}
#pragma mark - GetNodeEventResponseDelegate
- (void)getNodeEventResponseEdit:(NSInteger)rowIndex{
    self.selectRow = rowIndex;
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowIndex inSection:0];
    CGRect rectInTableView = [self.tableview rectForRowAtIndexPath:indexPath];
    CGRect rectInSuperview = [self.tableview convertRect:rectInTableView toView:[self.tableview superview]];
    [JMDropMenu showDropMenuFrame:CGRectMake(SCREEN_WIDTH - 140 - 20, rectInSuperview.origin.y+rectInSuperview.size.height+StatusBarAndNavigationBarHeight-100-20, 140, 250) ArrowOffset:60 TitleArr:@[
        @"删除",
        @"重命名",
        @"蓝牙固件升级",
        @"MCU固件升级",
        @"设为主节点"] ImageArr:@[@"",@"",@"",@"",@""] Type:JMDropMenuTypeQQ LayoutType:JMDropMenuLayoutTypeTitle RowHeight:50 Delegate:self];
}
- (void)getNodeEventResponseSwitch:(NSInteger)rowIndex sw:(BOOL)isSw{
    FDSMeshNodeModel *nodeModel = self.meshTool.nodeListWhitOutGroup[rowIndex];
    [FDSCommandApi changeLightSwitch:nodeModel.address isSwitch:isSw];
}
#pragma mark - JMDropMenuDelegate
- (void)didSelectRowAtIndex:(NSInteger)index Title:(NSString *)title Image:(NSString *)image{
    if (self.selectRow < self.meshTool.nodeListWhitOutGroup.count) {} else {
        return;
    }
    FDSMeshNodeModel *nodeModel = self.meshTool.nodeListWhitOutGroup[self.selectRow];
    if (index == 0) {
        // 删除
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"删除节点？" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
        [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {}]];
        [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
            dispatch_async(dispatch_get_main_queue(), ^{
                [SVProgressHUD show];
            });
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                if ([FDSMeshApi removeNode:nodeModel isSupportOutOfLine:YES]) {
                    [self.meshTool refreshNodesAndGroups];
                    self.meshTool.studioModel.meshJson = [FDSMeshApi getCurrentMeshJson];
                    [self.meshTool codingMeshData:self.meshTool.meshModel];
                    dispatch_async(dispatch_get_main_queue(), ^{
                        self.deviceCountLabel.text = [NSString stringWithFormat:@"设备列表：%lu",(unsigned long)self.meshTool.nodeListWhitOutGroup.count];
                        [self.tableview reloadData];
                        [SVProgressHUD showSuccessWithStatus:@"删除节点成功"];
                    });
                } else {
                    dispatch_async(dispatch_get_main_queue(), ^{
                        [SVProgressHUD showErrorWithStatus:@"删除节点失败！"];
                    });
                }
            });
        }]];
        [self presentViewController:alertController animated:YES completion:nil];
    } else if (index == 1) {
        // 重命名
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"重命名节点？" message:nil preferredStyle:(UIAlertControllerStyleAlert)];
        [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
            textField.text = nodeModel.name;
        }];
        [alertController addAction:[UIAlertAction actionWithTitle:@"取消" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {}]];
        [alertController addAction:[UIAlertAction actionWithTitle:@"确定" style:(UIAlertActionStyleDefault) handler:^(UIAlertAction * _Nonnull action) {
            UITextField *textfield = alertController.textFields.firstObject;
            if (textfield.text.length) {
                [FDSMeshApi renameNode:nodeModel name:textfield.text type:nodeModel.type firmwareVersion:nodeModel.firmwareVersion];
                [self.meshTool refreshNodesAndGroups];
                self.meshTool.studioModel.meshJson = [FDSMeshApi getCurrentMeshJson];
                [self.meshTool codingMeshData:self.meshTool.meshModel];
                [self.tableview reloadData];
            } else {
                [SVProgressHUD showErrorWithStatus:@"无效的节点名称！"];
            }
        }]];
        [self presentViewController:alertController animated:YES completion:nil];
    } else if (index == 2) {
        // 蓝牙固件升级
        if (nodeModel.state == FDS_DeviceStateOutOfLine) {
            [SVProgressHUD showErrorWithStatus:@"设备离线无法升级！"];
            return;
        }
        [FDSCommandApi getBleVersion:nodeModel.address completion:^(NSString * _Nonnull version, NSInteger paValue) {
            NSLog(@"%@",[NSString stringWithFormat:@"%@-蓝牙固件版本：%@, 固件类型：%02lX",nodeModel.name, version, (long)paValue]);
            [SVProgressHUD show];
            // 注意：这个版本从服务器获取，格式：“XXXXXX”HEX字符串
            NSString *firmwareVersion = @"";
            NSData *otaData = nil;
            // 注意：0x00或0xFF代表非PA，0x01代表PA，其它数字代表其它固件类型
            if (paValue == 0x00 || paValue == 0xFF) {
                // 非PA固件
                firmwareVersion = @"000060";
                otaData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"LK8620_MESH_GD_v000060_20250611_beta1" ofType:@"bin"]];
            } else if (paValue == 0x01) {
                // PA01固件
                firmwareVersion = @"000064";
                otaData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"LK8720_MESH_GD_v000064_20251118_beta" ofType:@"bin"]];
                // 打开PA固件设备升级限制（注意搭配startOTAWithOtaData升级接口使用）
                [FDSCommandApi openPAOTALimit:nodeModel.address];
            } else if (paValue == 0x03) {
                // PA03固件
                firmwareVersion = @"000057";
                otaData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"LK8720-03_MESH_GD_v000057_20251024_bate" ofType:@"bin"]];
                // 打开PA固件设备升级限制（注意搭配startOTAWithOtaData升级接口使用）
                [FDSCommandApi openPAOTALimit:nodeModel.address];
            }
            if (otaData.length == 0) {
                [SVProgressHUD showErrorWithStatus:@"无效的固件，无法升级！"];
                return;
            }
            BOOL isStart = [FDSMeshApi startOTAWithOtaData:otaData nodeModel:nodeModel progressAction:^(float progress){
                NSLog(@"progress->%.2f",progress);
                [SVProgressHUD showProgress:(progress/100.0) status:[NSString stringWithFormat:@"升级进度：%.2f%@",progress, @"%"]];
            } resultAction:^(BOOL isSuccess) {
                if (isSuccess) {
                    // 注：DEMO暂时注释过滤逻辑，APP根据实际情况使用过滤逻辑
                    /*
                    if (![self.filterList containsObject:nodeModel.macAddress]) {
                        [self.filterList addObject:nodeModel.macAddress];
                    }
                    // 注：升级成功后如果该设备需要手动复位，则设置过滤列表（设备列表尽量跟随studio保存到本地）
                    [FDSMeshApi filterAutoConnectedNode:self.filterList];
                    */
                    // 注：先过滤再停止OTA，避免过滤失效
                    [FDSMeshApi stopOTA];
                    // 注：需要更新节点蓝牙固件版本
                    [FDSMeshApi renameNode:nodeModel name:nodeModel.name type:nodeModel.type firmwareVersion:firmwareVersion];
                    [self.meshTool refreshNodesAndGroups];
                    self.meshTool.studioModel.meshJson = [FDSMeshApi getCurrentMeshJson];
                    [self.meshTool codingMeshData:self.meshTool.meshModel];
                    [SVProgressHUD showSuccessWithStatus:@"升级成功"];
                } else {
                    [FDSMeshApi stopOTA];
                    [SVProgressHUD showErrorWithStatus:@"升级失败！"];
                }
            }];
            if (!isStart) {
                [FDSMeshApi stopOTA];
                [SVProgressHUD showErrorWithStatus:@"升级失败！"];
            }
        }];
    } else if (index == 3) {
        // MCU固件升级
        if (nodeModel.state == FDS_DeviceStateOutOfLine) {
            [SVProgressHUD showErrorWithStatus:@"设备离线无法升级！"];
            return;
        }
        [SVProgressHUD show];
        UInt16 version = 0;
        NSData *otaData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"TP2R_TP4R_TP8R_V137" ofType:@"bin"]];
        BOOL isStart = [FDSMeshApi startMcuOTAWithOtaData:otaData version:version nodeModel:nodeModel progressAction:^(float progress) {
            NSLog(@"progress->%.2f",progress);
            [SVProgressHUD showProgress:(progress/100.0) status:[NSString stringWithFormat:@"升级进度：%.2f%@",progress, @"%"]];
        } resultAction:^(BOOL isSuccess) {
            [FDSMeshApi stopMcuOTA];
            if (isSuccess) {
                [SVProgressHUD showSuccessWithStatus:@"升级成功"];
            } else {
                [SVProgressHUD showErrorWithStatus:@"升级失败！"];
            }
        }];
        if (!isStart) {
            [FDSMeshApi stopMcuOTA];
            [SVProgressHUD showErrorWithStatus:@"升级失败！"];
        }
    } else if (index == 4) {
        // 设置主节点并重启网络
        [FDSMeshApi changeConnectedNode:nodeModel];
    }
}
#pragma mark - UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    if (section == 0) {
        return self.meshTool.nodeListWhitOutGroup.count;
    } else {
        if (self.meshTool.nodeListWhitOutGroup.count == 0) {
            return 1;
        }
        return 0;
    }
}
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    return 0.01;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    return 10.0;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.section == 0) {
        return 100;
    }
    return 300;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.section == 0) {
        NodeListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([NodeListTableViewCell class])];
        if (!cell){
            cell = [[NSBundle mainBundle] loadNibNamed:@"NodeListTableViewCell" owner:nil options:nil][0];
        }
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.rowIndex = indexPath.row;
        cell.delegate = self;
        FDSMeshNodeModel *nodeModel = self.meshTool.nodeListWhitOutGroup[indexPath.row];
        cell.titleLabel.text = nodeModel.name;
        cell.subTitleLabel.text = [NSString stringWithFormat:@"Type:%@, Addr:%04X, V:%02lX-%ld", nodeModel.type, nodeModel.address, (long)nodeModel.paValue, (long)nodeModel.firmwareVersion.integerValue];
        if (nodeModel.state == FDS_DeviceStateOutOfLine) {
            cell.iconImageview.image = [UIImage imageNamed:@"setting_04"];
        } else {
            cell.iconImageview.image = [UIImage imageNamed:@"setting_05"];
        }
        FDSMeshNodeModel *connectNode = [FDSMeshApi getConnectedNode];
        if ([connectNode.macAddress isEqualToString:nodeModel.macAddress]) {
            cell.titleLabel.textColor = [UIColor redColor];
        } else {
            cell.titleLabel.textColor = [UIColor blackColor];
        }
        return cell;
    } else {
        ListCreatTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([ListCreatTableViewCell class])];
        if (!cell){
            cell = [[NSBundle mainBundle] loadNibNamed:@"ListCreatTableViewCell" owner:nil options:nil][0];
        }
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        cell.delegate = self;
        cell.creatLabel.text = @"当前没有设备，请先添加设备~";
        [cell.creatButton setTitle:@"添加设备" forState:(UIControlStateNormal)];
        return cell;
    }
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if (indexPath.section == 0) {
        FDSMeshNodeModel *nodeModel = self.meshTool.nodeListWhitOutGroup[indexPath.row];
        TestViewController *viewController = [[TestViewController alloc] init];
        viewController.testModel = nodeModel;
        viewController.hidesBottomBarWhenPushed = YES;
        [self.navigationController pushViewController:viewController animated:YES];
    }
}

@end
